/*    file: main.cpp
 *    desc:
 * 
 * created: 2016-04-06
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include <stdio.h>
#include <iostream>
#include <fstream>

#include "BasicType.h"
#include "SharedPtr.h"
#include "TFileUtil.h"
#include <assert.h>
#include "TByteBuffer.h"
#include "TStringUtil.h"

#include "PsCaster.h"
#include "MediaPacket.h"

#include "Ffmpeg.h"
extern "C"
{
#include "libavutil/time.h"
}


class Application
{
public:
	Application():
		m_ifs(),
		m_file()
	{
		pscaster_init();
	}

	~Application()
	{
		close();

		pscaster_quit();
	}

	bool open(const std::string& indexPath, const std::string& dataPath)
	{
		m_ifs.open(indexPath.c_str());
		m_file = fopen(dataPath.c_str(), "rb");
		return m_ifs.is_open() && (m_file != NULL);
	}

	void close()
	{
		m_ifs.close();

		if (m_file)
		{
			fclose(m_file);
			m_file = NULL;
		}
	}

	av::MediaPacketPtr read()
	{
		av::MediaPacketPtr pkt;

		std::string line;
		std::getline(m_ifs, line);
		if (m_ifs.eof())
		{
			return av::MediaPacketPtr();
		}

		pkt.reset(new av::MediaPacket());
		if (!parseLine(line, pkt))
		{
			return av::MediaPacketPtr();
		}

		int size = pkt->size;

		pkt->ensure(size);

		int length = fread(pkt->data, 1, size, m_file);
		if (length != size)
		{
			return av::MediaPacketPtr();
		}

		pkt->size = length;

		return pkt;
	}

	bool parseLine(const std::string& line, av::MediaPacketPtr& pkt)
	{
		std::vector< std::string > segments;
		comn::StringUtil::split(line, ',', segments);
		if (segments.size() < 5)
		{
			return false;
		}

		comn::StringCast::toValue(segments[0], pkt->type);
		comn::StringCast::toValue(segments[1], pkt->size);
		comn::StringCast::toValue(segments[2], pkt->duration);
		comn::StringCast::toValue(segments[3], pkt->pts);
		comn::StringCast::toValue(segments[4], pkt->flags);

		return true;
	}

	std::ifstream	m_ifs;
	FILE*	m_file;

};

int main(int argc, char** argv)
{
	if (argc <= 2)
    {
		printf("DemoPsMux pkt.txt camera.h264");
        return EINVAL;
    }

	std::string indexPath = argv[1];
	std::string dataPath = argv[2];

	Application app;
	if (!app.open(indexPath, dataPath))
	{
		return 0;
	}

	MFormat format;
	memset(&format, 0, sizeof(format));
	format.codec = MCODEC_H264;
	format.width = 640;
	format.height = 480;
	format.clockRate = 1000000;

	format.channels = 1;
	format.sampleRate = 8000;

	PsCasterParams params;
	params.payload = 96;
	params.ssrc = 1;

	caster_t handle = -1;
	int ret = pscaster_openEx(&handle, PSCASTER_PROTOCOL_RTP, 0, &format, &params);

	pscaster_add_target(handle, "192.168.3.53", 10000);

	while (true)
	{
		av::MediaPacketPtr pkt = app.read();
		if (!pkt)
		{
			break;
		}

		if (pkt->size == 25 && pkt->flags == 1)
		{
			//continue;
		}

		MPacket packet;
		memset(&packet, 0, sizeof(packet));
		packet.data = pkt->data;
		packet.size = pkt->size;
		packet.type = pkt->type;
		packet.pts = pkt->pts;
		packet.duration = 0;
		packet.flags = pkt->flags;

		packet.pts -= 469959889274;

		printf("type:%d, size:%d, flags:%d, pts:%lld\n", packet.type, packet.size, packet.flags, packet.pts);

		std::string data = comn::StringCast::toHexGroupString(packet.data, 16);
		printf("%s\n", data.c_str());
		
		comn::FileUtil::write(packet.data, packet.size, "in.h264", true);

		pscaster_write(handle, &packet);

		av_usleep(1000 * 30);
	}

	pscaster_close(handle);

	app.close();

	return 0;
}




